﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
using Utilify.Framework;
using Application = Utilify.Framework.Application;
using Job = Utilify.Framework.Job;

namespace Utilify.Platform.Demo.RayTracer
{
    public class Program
    {
        private static Application _app;
        private static IList<Job> _utilifyJobs;
        private static AdditionJob _testJob;
        private static List<String> _remoteSpecificFiles;
        private static ConnectionSettings _connectionSettings;
      //  private static List<UtilifyClassesDataContext> _dataContexts;
        private const uint JobsCount= 10;


        private static void Main()
        {

            //initalize connection settings with appropriate crediantals
            InitCrediantals();

            //Specifying remote files' filenames
            _remoteSpecificFiles = new List<string>
                                       {
                                           "config0.xml",
                                           "config1.xml",
                                           "config2.xml",
                                           "config3.xml",
                                           "config4.xml",
                                           "config5.xml",
                                           "config6.xml",
                                           "config7.xml",
                                           "config8.xml",
                                           "config9.xml"
                                       };


           
            
           

/*
            XmlSerializer serializer = new XmlSerializer(typeof(RequestConfig));

            //Testing deserialization
            StreamReader reader = new StreamReader(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\input.xml");
            var inputRequestConfig = (RequestConfig)serializer.Deserialize(reader);
 */
            RequestConfig inputRequestConfig = null;
            //Testing serialization !
          //  RequestConfig requestConfig = new RequestConfig("Mid", "DefaultTime", "ProrataTemporisEnd", "ACT/360");
      
         /*   
            StreamWriter writer = new StreamWriter(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\RequestConfig.xml");
          serializer.Serialize(writer,inConfigRequest);
            // serializer.Serialize(writer, requestConfig);
            writer.Close(); 
          */
        




            // Create Jobs list to track Job statuses
            _utilifyJobs = new List<Job>();




            // Buliding the application dependencies
            List<DependencyInfo> dependencies = DependencyResolver.DetectDependencies(typeof (AdditionJob));

            var dependencyInfo = new DependencyInfo("Utilify.Framework",
                                                    @"C:\Users\phoewass\Documents\Visual Studio 2010\Projects\RayTracer\lib\Utilify.Framework.dll",
                                                    DependencyType.NativeModule);

            dependencies.Add(dependencyInfo);


            // Creating the container application which executes the remote jobs 
            _app = new Application("Utilify Test " + DateTime.UtcNow.Ticks,
                                   QosInfo.GetDefault(), dependencies, _connectionSettings);


            //Creating remote jobs with appropriate configuration/variables
            for (int i = 0; i < JobsCount; i++)
            {
                AdditionJob job = new AdditionJob(i, i, inputRequestConfig, _remoteSpecificFiles[i % _remoteSpecificFiles.Count]);
                
                //Initialization of the worker name and start time beause it can't be done else where
               // job.WorkerName= 
                




             Job remoteJob = _app.AddJob(job);
             _utilifyJobs.Add(remoteJob);
            }



            //Start the main application
            try
            {
                _app.Start();

            }
            catch (Exception ex)
            {
                Console.WriteLine("Problem Contacting Utilify Manager.\n" + ex.Message + "\nException: " + ex.GetType());


            }


            //Waiting for remote jobs completion and displaying results
             foreach (Job remoteJob in _utilifyJobs)
            {
          
            remoteJob.WaitForCompletion();


            var myJob = (AdditionJob) remoteJob.CompletedInstance; //remoteJob.CompletedInstance;
            if (myJob != null)
            {
           

                /*
                   Console.WriteLine("Are my sums right? {0} + {1} + xml input {2} = {3}", myJob.GetValueA(),
                                  myJob.GetValueB(),myJob.GetInputValue(),
                                  myJob.GetResult());
                 */
              //  if (myJob.DatabaseDependencyFile == null)
               // {
                    Console.WriteLine("Are my sums right? {0} + {1} = {2} ", myJob.GetValueA(), myJob.GetValueB(),
                                      myJob.GetResult());
                    Console.WriteLine("Job Id text {0}", myJob.GetConfigId());

                    Console.WriteLine("Worker name : {0}", myJob.DatabaseDependencyFile);
                    //myJob.RemoteResult.CalculatedResult
                //SaveResults(remoteJob);
                   /* foreach (String query in myJob.Queries)
                    {
                        Console.WriteLine(query);
                    }*/
              //  }

                Result remoteResult = myJob.RemoteResult;
                remoteResult.StartTime = remoteJob.StartTime.ToString();
                remoteResult.EndTime = remoteJob.FinishTime.ToString();
                SerializeToXML(remoteResult);
                
                Console.WriteLine(_app.Id);

                //Get the remote working Directory
                //Console.WriteLine(myJob.GetWorkingDirectory());


            }
          //  Console.WriteLine(remoteJob.ExecutionException);

        }

        Console.WriteLine("Finished all sums");
           

            Console.ReadKey();
        }




        private static void InitCrediantals()
        {
            // Add crediantals options to connect to the Utilify Manager
            _connectionSettings = new ConnectionSettings();
            _connectionSettings.Host = "localhost";
            _connectionSettings.Port = 8080;
            _connectionSettings.CredentialType = CredentialType.Username;
            _connectionSettings.ServiceCertificate.DnsIdentity = "Utilify.Platform.Manager";
            _connectionSettings.UsernameCredential.Username = "admin";
            _connectionSettings.UsernameCredential.Password = "admin";

        }



        private static void SerializeToXML(Result result)
        {
            if (result != null)
            {
                XmlSerializer serializer = new XmlSerializer(typeof (Result));
                TextWriter textWriter = new StreamWriter("./" + result.FileName);
                serializer.Serialize(textWriter, result);
                textWriter.Close();
            }
        }




     /*  private static void app_JobCompleted(object sender, JobCompletedEventArgs e)
       {
        // Get the job results and write the data to the result files
        ResultStatusInfo[] results = _app.GetJobResults(e.Job);
         foreach (ResultStatusInfo result in results)
         {
            ResultContent content = _app.GetResultContent(result.ResultId);
            using (FileStream resultFile = File.Create("./" + result.Info.FileName)) 
            {
            resultFile.Write(content.GetContent(), 0, content.GetContent().Length);
            }
         }
       }*/
 }

  

}